
package CtrlLayer;
import ModelLayer.*;
import DBLayer.*;
import java.util.ArrayList;

/**
 * @version 12/22/2011
 * @author Gruppe 4
 */
public class CtrlOrder 
{
    private Order order;
    private CtrlPerson ctrlPerson;
    private CtrlTask ctrlTask;
    private CtrlMachine ctrlMachine;
    private CtrlProduct ctrlProduct;
    private PartOrder po;
    private IFDBOrder dbOrder;
    
    /**
     * Creates a new instance of CtrlOrder
     */
    public CtrlOrder()
    {
        order = new Order();
        ctrlPerson = new CtrlPerson();
        ctrlTask = new CtrlTask();
        ctrlMachine = new CtrlMachine();
        ctrlProduct = new CtrlProduct();
        po = new PartOrder();
        dbOrder = new DBOrder();
    }
    
    /**
     * Method to get an ArrayList with orders from a specific customer, used in ListModelSearchPersonOrder
     * @param customerId int customerId the id of the Customer
     * @param retrieveAssociation 
     * @return returns an ArrayList with orders for a specific customer
     */
    public ArrayList<Order> findOrders(int customerId, boolean retrieveAssociation)
    {
        return dbOrder.findOrders(customerId, retrieveAssociation);
    }
    
    /**
     * Method to get an ArrayList with order with a specific orderId
     * @param orderId int orderId the id of the order
     * @param retrieveAssociation
     * @return returns an ArrayList with orders
     */
    public ArrayList<Order> findOrdersByOrderId(int orderId, boolean retrieveAssociation)
    {
        return dbOrder.findOrdersByOrderId(orderId, retrieveAssociation);
    }
    
    /**
     * Method that finds an Order with a specific orderID
     * @param orderId int orderId the id of the order 
     * @param retrieveAssociation
     * @return returns an Order object
     */
    public Order findOrderById(int orderId, boolean retrieveAssociation)
    {
        return dbOrder.searchOrderId(orderId, retrieveAssociation);
    }
    
    /**
     * Method that finds an Order with a specific date
     * @param orderDate String orderDate the date the order has been made
     * @return returns an ArrayList with orders made on a specific date
     */
    public ArrayList<Order> findOrderByDate(String orderDate)
    {
        return dbOrder.searchOrderDate(orderDate, false);
    }
    
    /**
     * 
     * @param orderDate String orderDate the date the order is accepted
     * @param tasks Task tasks a Task wanted to set on the order
     * @param tenderDate String tenderDate the date the tender is generated
     * @param tenderStatus int tenderStatus the status of the tender, if it is a tender or order
     * @param totalPrice double totalPrice, the totalPrice of the tender
     * @param customer Customer the customer ordering the tender
     * @param invoice Invoice the invoice created for the tender
     * @return returns an int 1 if the method succedes and -1 if the method fails
     */
    public int updateOrder(String orderDate, Task tasks, String tenderDate,int tenderStatus,
                           double totalPrice, Customer customer, Invoice invoice)
    {
        order.setOrderDate(orderDate);
        order.setTenderDate(tenderDate);
        order.setTenderStatus(tenderStatus);
        order.setTotalPrice(totalPrice);
        order.setCustomer(customer);
        order.setTasks(tasks);
        order.setInvoice(invoice);
        return dbOrder.updateOrder(order);  
    }
    
    /**
     * Method that deletes an order from the database
     * @param orderId int orderId the id of the order 
     */
    public void deleteOrder(int orderId )
    {
        dbOrder.deleteOrder(orderId);
    }
    
    /**
     * Method to start a sale
     * @param customer Customer customer the customer who ordered the tender
     * @param employeeId int employeeId the id of the employee who is calculating the tender
     * @param currentDate String currentDate the current date
     * @param taskName String taskName the name of the type of task
     * @param disclaimer String disclaimer the disclaimer wanted to set on the tender
     * @param startDate String startDate the day work on the order will begin
     * @param endDate String endDate the date the tender ends
     */
    public void startSale(Customer customer, int employeeId, String currentDate,
             String taskName, String disclaimer, String startDate, String endDate)
    { 
        order.setTenderDate(currentDate);
        order.setTenderStatus(1);
        order.setCustomer(customer);
        order.setEmployee(ctrlPerson.findPersonById(employeeId, true));
        order.setInvoice(null);
        
        order.setTasks(setTask(taskName, disclaimer, startDate, endDate));
    }
    
    /**
     * Method to add an employee to an order
     * @param employeeId int employeeId the id of the employee who will work on the task
     * @param amount double amount the hours the employee will work on the order
     * @return returns a PartOrder with an employee
     */
    public PartOrder addEmployee(int employeeId, double amount)
    {
        Person p = ctrlPerson.findPersonById(employeeId, true);
        System.out.println(p);
        
        po = setPartOrder(p, amount);
        order.getTasks(0).setPartOrders(po);
        
        return po;
    }
    
    /**
     * Method to add a Machine to the order
     * @param machineId int machineId the id of the machine which will be used on the order
     * @param amount double amount the number of hours the machine will work
     * @return returns a PartOrder with a machine
     */
    public PartOrder addMachine(int machineId, double amount)
    {
        Machine m = ctrlMachine.findMachine(machineId, false);
        
        po = setPartOrderMachine(m, amount);
        order.getTasks(0).setPartOrders(po);
        return po;
    }
    
    /**
     * Method to add a product to an order
     * @param productId int productId the id of a product who is needed in the order
     * @param amount double amount the number of instances of a product which is needed for the order
     * @return Returns a PartOrder object with a Product
     */
    public PartOrder addProduct(int productId, double amount)
    {
        ProductDescription pd = ctrlProduct.findProduct(productId, false);
        System.out.println(pd);
        
        po = setPartOrderProduct(pd, amount);
        order.getTasks(0).setPartOrders(po);
        
        return po;
    }
    
    /**
     * Methodcall to create a task 
     * @param taskName String taskName the name of the task
     * @param disclaimer String disclaimer the disclainer wanted to use for the tender
     * @param startDate String startDate the date the job will begin
     * @param endDate String endDate the date the job will be done
     * @return returns a Task object
     */
    public Task setTask(String taskName, String disclaimer, String startDate, String endDate)
    {
        return ctrlTask.createTask(taskName, disclaimer, startDate, endDate);
    }
    
    /**
     * Method to create a partOrder 
     * @param person Person person the person wanted to add
     * @param amount double amount the hours the person has to work
     * @return returns a PartOrder
     */
    private PartOrder setPartOrder(Person person, double amount)
    {
        Employee employee = (Employee) person;
        PartOrder partOrder = new PartOrder();
        
        partOrder.setEmployee(employee);
        partOrder.setAmount(amount);
        
        System.out.println(partOrder);
        return partOrder;
    }
    
    /**
     * Method to create a partOrder with a machine
     * @param m Machine m the machine wanted to use for the job
     * @param amount double amount the amount of hours the machine is set to be used for the job
     * @return returns a PartOrder
     */
    private PartOrder setPartOrderMachine(Machine m, double amount)
    {
        PartOrder partOrder = new PartOrder();
        
        partOrder.setMachine(m);
        partOrder.setAmount(amount);
        
        System.out.println(partOrder);
        return partOrder;
    }
    
    /**
     * Method to create a PartOrder with a product
     * @param pd ProductDescription the productDescription for the product neede for the job
     * @param amount double amount the number of pieces of the product that is needed
     * @return returns a PartOrder
     */
    private PartOrder setPartOrderProduct(ProductDescription pd, double amount)
    {
        PartOrder partOrder = new PartOrder();
        
        partOrder.setProDesc(pd);
        partOrder.setAmount(amount);
        
        System.out.println(partOrder);
        return partOrder;
    }
    
    /**
     * Method that sets the total price on the order
     * @param totalPrice double totalPrice, the total price for the tender
     */
    public void setTotal(double totalPrice)
    {
        order.setTotalPrice(totalPrice);
    }
    
    /**
     * Method to end a sale
     */
    public void endSale()
    {
        
        DBConnection con = DBConnection.getInstance();
           try
           {
                int orderId = dbOrder.getMaxId();
                DBConnection.startTransaction();
                dbOrder.insertOrder(order);
                
                for(int i = 0 ; i < order.getSize(); i++)
                {
                    Task task = order.getTasks(i);
                    ctrlTask.insertNewTask(task, orderId);
                    
                    for(int j = 0; j < task.getSize(); j++)
                    {
                        PartOrder partOrder = task.getPartOrders(j);
                        ctrlTask.insertNewPartOrder(partOrder);
                    }//end for
                }//end for
                DBConnection.commitTransaction();
           }//end try
           catch(Exception e)
           {
                DBConnection.rollbackTransaction();
                System.out.println("Transaction has been rolled back");
                System.out.println(e.getMessage());
           }//end catch
    } 
}